package com.nidu.demo.dept.executor.command;

import com.alibaba.cola.dto.Response;
import com.alibaba.cola.dto.SingleResponse;
import com.nidu.demo.company.ability.CompanyDomainService;
import com.nidu.demo.dept.dto.DepartmentUpdateCmd;
import com.nidu.demo.common.enums.StatusEnum;
import com.nidu.demo.dept.ability.DepartmentDomainService;
import com.nidu.demo.dept.convertor.DepartmentConvertor;
import com.nidu.demo.dept.dto.DepartmentCO;
import com.nidu.demo.dept.gateway.DepartmentGateway;
import com.nidu.demo.dept.model.Department;
import com.nidu.demo.dept.util.DepartmentUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.util.List;

/**
 * 部门更新命令执行器
 *
 * @author auto
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class DepartmentUpdateCmdExe {

    private final DepartmentGateway gateway;

    private final DepartmentDomainService domainService;

    private final DepartmentConvertor convertor;

    private final CompanyDomainService companyDomainService;

    public SingleResponse<DepartmentCO> execute(DepartmentUpdateCmd cmd) {
        // 2. 转换为领域对象
        Department dept = Department.update(cmd.getId(), cmd.getDeptName(), cmd.getDeptCode(), cmd.getParentId(), 
                cmd.getCompanyId(), cmd.getRemark(), cmd.getSortOrder(),
                cmd.getLeader(), cmd.getPhoneNumber(), cmd.getEmail());


        // 3. 校验数据
        // 2.检查公司是否存在
        companyDomainService.validateCompany(dept.getCompanyId());
        // 3.检查对象是否已存在
        domainService.validateDuplicate(dept.getDeptCode(), dept.getCompanyId(), dept.getId());
        Department oldDepartment = domainService.validateDept(dept.getId());
        Department parent = domainService.validateParent(dept.getParentId());

        // 4. 检查父部门ID发生变化
        if (!oldDepartment.getParentId().equals(dept.getParentId())) {
            // 4.1 构建新的ancestors路径
            String newAncestors = DepartmentUtil.buildAncestors(cmd.getParentId(), parent);
            dept.setAncestors(newAncestors);
            
            // 4.2 更新当前部门
            Department savedDept = gateway.update(dept);
            
            // 4.3 更新所有子部门的ancestors
            updateChildrenAncestors(cmd.getId(), newAncestors);
            
            // 5. 转换为DTO返回
            DepartmentCO deptCO = convertor.toClientObject(savedDept);
            return SingleResponse.of(deptCO);
        } else {
            // 5. 父部门未变化，直接更新
            dept.setAncestors(oldDepartment.getAncestors());
            Department save = gateway.update(dept);
            DepartmentCO deptCO = convertor.toClientObject(save);
            return SingleResponse.of(deptCO);
        }
    }

    public Response updateStatus(Long id, StatusEnum status) {
        domainService.updateStatus(id, status);
        return Response.buildSuccess();
    }

    /**
     * 递归更新所有子部门的ancestors
     * @param deptId 当前部门ID
     * @param newAncestors 新的ancestors路径
     */
    private void updateChildrenAncestors(Long deptId, String newAncestors) {
        // 查询所有直接子部门
        List<Department> children = gateway.getByParentId(deptId);
        
        if (children.isEmpty()) {
            return;
        }
        
        log.info("更新部门[{}]的{}个子部门ancestors", deptId, children.size());
        
        for (Department child : children) {
            // 构建子部门的新ancestors：父部门的ancestors + 父部门ID
            String childNewAncestors = DepartmentUtil.buildAncestors(newAncestors, deptId);

            // 更新子部门的ancestors
            child.setAncestors(childNewAncestors);
            gateway.update(child);
            
            log.debug("更新子部门[{}]的ancestors: {}", child.getId(), childNewAncestors);

            // 递归更新子部门的子部门
            updateChildrenAncestors(child.getId(), childNewAncestors);
        }
    }

} 